/**
 * Copyright &copy; 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
 */
package com.jeeplus.sys.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeeplus.aop.demo.annotation.DemoMode;
import com.jeeplus.aop.logging.annotation.ApiLog;
import com.jeeplus.core.query.QueryWrapperGenerator;
import com.jeeplus.sys.constant.CommonConstants;
import com.jeeplus.sys.domain.Role;
import com.jeeplus.sys.service.RoleService;
import com.jeeplus.sys.service.UserService;
import com.jeeplus.sys.service.dto.RoleDTO;
import com.jeeplus.sys.service.dto.UserDTO;
import com.jeeplus.sys.utils.UserUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

/**
 * 角色Controller
 *
 * @author jeeplus
 * @version 2021-12-05
 */
@RestController
@RequestMapping("/sys/role")
public class RoleController {

    @Autowired
    private RoleService roleService;
    @Autowired
    private UserService userService;

    /**
     * 角色列表数据
     *
     * @param role
     * @param page
     * @return
     */
    @ApiLog("查询角色列表")
    @PreAuthorize("hasAuthority('sys:role:list')")
    @GetMapping("list")
    public ResponseEntity <IPage <Role>> data(Role role, Page <Role> page) throws Exception {
        QueryWrapper <Role> queryWrapper = QueryWrapperGenerator.buildQueryCondition ( role, Role.class );
        IPage <Role> result = roleService.page ( page, queryWrapper );
        return ResponseEntity.ok ( result );
    }


    /**
     * 按id查询
     *
     * @param id
     * @return
     */
    @ApiLog("查询角色")
    @PreAuthorize("hasAnyAuthority('sys:role:view','sys:role:add','sys:role:edit')")
    @GetMapping("queryById")
    public ResponseEntity <RoleDTO> queryById(@RequestParam String id) {
        RoleDTO roleDTO = roleService.get ( id );
        String newDataRuleIds = "";
        if ( roleDTO != null ) {
            if ( StrUtil.isNotBlank ( roleDTO.getDataRuleIds ( ) ) ) {
                for (String rId : roleDTO.getDataRuleIds ( ).split ( "," )) {
                    newDataRuleIds = newDataRuleIds + "dataRule-" + rId + ",";
                }
            }
            if ( newDataRuleIds.length ( ) > 1 ) {
                roleDTO.setDataRuleIds ( newDataRuleIds.substring ( 0, newDataRuleIds.length ( ) - 1 ) );
            }
            roleDTO.setMenuIdList ( roleService.queryAllNotChildrenMenuId ( roleDTO.getId ( ) ) );
        }

        return ResponseEntity.ok ( roleDTO );
    }

    /**
     * 保存角色
     *
     * @param roleDTO
     * @return
     */
    @ApiLog("保存角色")
    @PreAuthorize("hasAnyAuthority('sys:role:assign','sys:role:auth','sys:role:add','sys:role:edit')")
    @PostMapping("save")
    public ResponseEntity save(@Valid @RequestBody RoleDTO roleDTO) {
        String sysData = CommonConstants.NO;
        if ( StrUtil.isNotEmpty ( roleDTO.getId ( ) ) ) {
            sysData = roleService.get ( roleDTO.getId ( ) ).getSysData ( );
        }
        if ( !UserUtils.getCurrentUserDTO ( ).isAdmin ( ) && (CommonConstants.YES.equals ( sysData ) || CommonConstants.YES.equals ( roleDTO.getSysData ( ) )) ) {
            return ResponseEntity.badRequest ( ).body ( "无权操作，只有超级管理员才能创建/修改系统数据。" );
        }
        roleService.saveOrUpdate ( roleDTO );
        return ResponseEntity.ok ( "保存角色成功!" );
    }


    /**
     * 角色授权
     *
     * @param roleDTO
     * @return
     */
    @ApiLog("角色授权")
    @PreAuthorize("hasAnyAuthority('sys:role:assign','sys:role:auth')")
    @PostMapping("assignAuthorityToRole")
    public ResponseEntity assignAuthorityToRole(@Valid @RequestBody RoleDTO roleDTO) {
        String sysData = roleService.get ( roleDTO.getId ( ) ).getSysData ( );
        if ( !UserUtils.getCurrentUserDTO ( ).isAdmin ( ) && CommonConstants.YES.equals ( sysData ) ) {
            return ResponseEntity.badRequest ( ).body ( "无权操作，只有超级管理员才能修改此数据。" );
        }
        if ( StrUtil.isNotBlank ( roleDTO.getDataRuleIds ( ) ) ) {
            String dataRuleIds = roleDTO.getDataRuleIds ( );
            String newDataRuleIds = "";
            String[] ruleIds = dataRuleIds.split ( "," );
            for (String ruleId : ruleIds) {
                if ( ruleId.startsWith ( "dataRule-" ) ) {
                    newDataRuleIds = newDataRuleIds + ruleId.substring ( 9 ) + ",";
                }
            }
            if ( newDataRuleIds.length ( ) > 1 ) {
                roleDTO.setDataRuleIds ( newDataRuleIds.substring ( 0, newDataRuleIds.length ( ) - 1 ) );
            }

        }
        roleService.assignAuthorityToRole ( roleDTO );
        return ResponseEntity.ok ( "角色授权成功!" );
    }


    /**
     * 删除角色
     *
     * @param ids
     * @return
     */
    @DemoMode
    @ApiLog("删除角色")
    @PreAuthorize("hasAuthority('sys:role:del')")
    @DeleteMapping("delete")
    public ResponseEntity <String> delete(String ids) {
        StringBuffer msg = new StringBuffer ( );
        for (String id : ids.split ( "," )) {
            RoleDTO roleDTO = roleService.get ( id );
            if ( !UserUtils.getCurrentUserDTO ( ).isAdmin ( ) && roleDTO.getSysData ( ).equals ( CommonConstants.YES ) ) {
                msg.append ( "无权操作，只有超级管理员才能修改[" + roleDTO.getName ( ) + "]数据。" );
            } else {
                roleService.deleteRole ( id );
                msg.append ( "删除角色[" + roleDTO.getName ( ) + "]成功。" );
            }
        }
        return ResponseEntity.ok ( msg.toString ( ) );
    }

    /**
     * 获取所属角色用户
     *
     * @return
     */
    @ApiLog("获取所属角色用户")
    @PreAuthorize("hasAuthority('sys:role:assign')")
    @GetMapping("assign")
    public ResponseEntity assign(UserDTO userDTO, Page <UserDTO> page) throws Exception {
        QueryWrapper <UserDTO> queryWrapper = QueryWrapperGenerator.buildQueryCondition ( userDTO, UserDTO.class );
        IPage <UserDTO> result = userService.findPageByRole ( page, queryWrapper );
        return ResponseEntity.ok ( result );
    }


    /**
     * 角色分配 -- 从角色中移除用户
     *
     * @param userId
     * @param roleId
     * @return
     */
    @DemoMode
    @ApiLog("从角色中移除用户")
    @PreAuthorize("hasAuthority('sys:role:assign')")
    @DeleteMapping("removeUserFromRole")
    public ResponseEntity removeUserFromRole(String userId, String roleId) {
        RoleDTO role = roleService.get ( roleId );
        UserDTO user = userService.get ( userId );
        if ( UserUtils.getCurrentUserDTO ( ).getId ( ).equals ( userId ) && !UserUtils.getCurrentUserDTO ( ).isAdmin ( ) ) {
            return ResponseEntity.badRequest ( ).body ( "无法从角色【" + role.getName ( ) + "】中移除用户【" + user.getName ( ) + "】自己！" );
        } else {
            if ( user.getRoleDTOList ( ).size ( ) <= 1 ) {
                return ResponseEntity.badRequest ( ).body ( "用户【" + user.getName ( ) + "】从角色【" + role.getName ( ) + "】中移除失败！这已经是该用户的唯一角色，不能移除。" );
            } else {
                Boolean flag = roleService.removeUserFromRole ( role, user );
                if ( !flag ) {
                    return ResponseEntity.badRequest ( ).body ( "用户【" + user.getName ( ) + "】从角色【" + role.getName ( ) + "】中移除失败！" );
                } else {
                    return ResponseEntity.ok ( "用户【" + user.getName ( ) + "】从角色【" + role.getName ( ) + "】中移除成功！" );
                }
            }
        }
    }

    /**
     * 添加用户到角色
     *
     * @param roleId
     * @param userIds
     * @return
     */
    @DemoMode
    @ApiLog("添加用户到角色")
    @PreAuthorize("hasAuthority('sys:role:assign')")
    @PutMapping("addUserToRole")
    public ResponseEntity addUserToRole(String roleId, String[] userIds) {
        StringBuilder msg = new StringBuilder ( );
        int newNum = 0;
        RoleDTO roleDTO = roleService.get ( roleId );
        for (int i = 0; i < userIds.length; i++) {
            UserDTO user = roleService.addUserToRole ( roleDTO, userService.get ( userIds[i] ) );
            if ( user != null ) {
                msg.append ( "<br/>新增用户【" + user.getName ( ) + "】到角色【" + roleDTO.getName ( ) + "】！" );
                newNum++;
            }
        }
        return ResponseEntity.ok ( "已成功分配 " + newNum + " 个用户" + msg );
    }

    /**
     * 验证角色名是否存在
     *
     * @param role
     * @return
     */
    @ApiLog("验证角色名是否存在")
    @GetMapping("validateNotExist")
    public ResponseEntity validateExist(Role role) {

        role = roleService.lambdaQuery ( ).eq ( StrUtil.isNotBlank ( role.getName ( ) ), Role::getName, role.getName ( ) )
                .eq ( StrUtil.isNotBlank ( role.getEnName ( ) ), Role::getEnName, role.getEnName ( ) ).one ( );

        if ( role == null ) {
            return ResponseEntity.ok ( true );
        } else {
            return ResponseEntity.ok ( false );
        }
    }

}
